package pro.cherish.dao.redis.config;

/**
 * @author 创建人：cherish
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2019-11-02 cherish 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：RedisCacheConfig
 * @Description 功能说明：缓存配置
 * <p>
 * TODO
 * </p>
 * **********************************************************************
 * @date 创建日期： 2019-11-02 cherish
 */

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.*;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import pro.cherish.dao.redis.constant.RedisConstant;
import pro.cherish.knowledgeutil.array.ArrayUtilsExt;
import pro.cherish.knowledgeutil.json.JsonUtilExt;

import java.lang.reflect.Method;

@Configuration
@ConditionalOnClass(CacheConfig.class)
@EnableCaching
public class RedisCacheConfig {
    String prefix = RedisConstant.SESSION + "M";

    /**
     * 设置key生成策略
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            /** 重写生成key方法 */
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder(prefix);
                CacheConfig cacheConfig = o.getClass().getAnnotation(CacheConfig.class);
                Cacheable cacheable = method.getAnnotation(Cacheable.class);
                CachePut cachePut = method.getAnnotation(CachePut.class);
                CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class);
                if (cacheable != null) {
                    String[] cacheNames = cacheable.value();
                    if (ArrayUtilsExt.isNotEmpty(cacheNames)) {
                        sb.append(cacheNames[0]);
                    }
                } else if (cachePut != null) {
                    String[] cacheNames = cachePut.value();
                    if (ArrayUtilsExt.isNotEmpty(cacheNames)) {
                        sb.append(cacheNames[0]);
                    }
                } else if (cacheEvict != null) {
                    String[] cacheNames = cacheEvict.value();
                    if (ArrayUtilsExt.isNotEmpty(cacheNames)) {
                        sb.append(cacheNames[0]);
                    }
                }
                if (cacheConfig != null && sb.toString().equals(prefix)) {
                    String[] cacheNames = cacheConfig.cacheNames();
                    if (ArrayUtilsExt.isNotEmpty(cacheNames)) {
                        sb.append(cacheNames[0]);
                    }
                }
                if (sb.toString().equals(prefix)) {
                    sb.append(o.getClass().getName()).append(".").append(method.getName());
                }
                sb.append(":");
                if (objects != null) {
                    for (Object object : objects) {
                        sb.append(JsonUtilExt.toJsonString(object));
                    }
                }
                return sb.toString();
            }
        };
    }

    /**
     * 缓存管理器，可以使用注解@cacheable等注解
     *
     * @param connectionFactory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        RedisCacheManager rcm = RedisCacheManager.builder(connectionFactory).build();
        return rcm;
    }
}
